package com.dreamer.ratioprogresslibrary;

import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.app.Context;

/**
 * Created by ysx on 2016/7/2.
 */
public class RatioProgressBar extends Component implements Component.DrawTask {

    private static final String TAG = RatioProgressBar.class.getSimpleName();
    private final String LEFT_PROGRESS_VALUE = "left_progress_value";
    private final String LEFT_PROGRESS_BG = "left_progress_bg";
    private final String RIGHT_PROGRESS_VALUE = "right_progress_value";
    private final String RIGHT_PROGRESS_BG = "right_progress_bg";
    private final String LEFT_RIGHT_PROGRESS_SPACING = "left_right_progress_spacing";
    private final String PROGRESS_ANIM_DURATION = "progress_anim_duration";
    private final String PROGRESS_HEIGHT = "progress_height";

    private Paint mLeftPaint;
    private Paint mRightPaint;

    /**
     * 左、右进度条的宽度
     */
    private int mLeftWidthX;
    private int mRightWidthX;
    private int mTotalValue;
    private int mLeftValue = 0;
    private int mRightValue = 0;
    private int leftProgressBg = 0xDD2F1C;
    private int rightProgressBg = 0x1D69E1;
    /**
     * 进度条的高度，默认15px
     */
    private int mProgressHeight = 15;
    /**
     * 左、右进度条之间的间隔，默认1px
     */
    private int mLeftRightProgressSpacing = 1;
    /**
     * 进度条动画持续时间
     */
    private int mProgressAnimDuration = 3000;

    public RatioProgressBar(Context context) {
        this(context, null);
    }

    public RatioProgressBar(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public RatioProgressBar(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);

        if (attrSet != null) {
            attrSet.getAttr(LEFT_PROGRESS_VALUE).ifPresent(attr -> mLeftValue = attr.getIntegerValue());
            attrSet.getAttr(RIGHT_PROGRESS_VALUE).ifPresent(attr -> mRightValue = attr.getIntegerValue());
            attrSet.getAttr(LEFT_PROGRESS_BG).ifPresent(attr -> leftProgressBg = attr.getColorValue().getValue());
            attrSet.getAttr(RIGHT_PROGRESS_BG).ifPresent(attr -> rightProgressBg = attr.getColorValue().getValue());
            attrSet.getAttr(LEFT_RIGHT_PROGRESS_SPACING).ifPresent(attr -> mLeftRightProgressSpacing = attr.getIntegerValue());
            attrSet.getAttr(PROGRESS_ANIM_DURATION).ifPresent(attr -> mProgressAnimDuration = attr.getIntegerValue());
            attrSet.getAttr(PROGRESS_HEIGHT).ifPresent(attr -> mProgressHeight = attr.getDimensionValue());
        }
        mTotalValue = calculateTotalProgressValue();

        mLeftPaint = new Paint();
        mLeftPaint.setAntiAlias(true);
        mLeftPaint.setStrokeCap(Paint.StrokeCap.SQUARE_CAP);
        mLeftPaint.setColor(new Color(leftProgressBg));
        mLeftPaint.setStrokeWidth(mProgressHeight);

        mRightPaint = new Paint();
        mRightPaint.setAntiAlias(true);
        mRightPaint.setStrokeCap(Paint.StrokeCap.SQUARE_CAP);
        mRightPaint.setColor(new Color(rightProgressBg));
        mRightPaint.setStrokeWidth(mProgressHeight);

        addDrawTask(this);
        startProgressAnim();
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        canvas.drawLine(new Point(0, getHeight() / 2), new Point(mLeftWidthX, getHeight() / 2), mLeftPaint);
        canvas.drawLine(new Point(getWidth(), getHeight() / 2), new Point(mRightWidthX, getHeight() / 2), mRightPaint);
    }

    private void startProgressAnim() {
        AnimatorValue animator = new AnimatorValue();
        animator.setDuration(mProgressAnimDuration);
        animator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                mLeftWidthX = (int) (value * calculateLeftProgressWidth());
                mRightWidthX = (int) (getWidth() - value * calculateRightProgressWidth());
                getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
                    @Override
                    public void run() {
                        invalidate();
                    }
                });
            }
        });
        animator.start();
    }

    public void setLeftProgressValue(int progress) {
        mLeftValue += progress;
        resetProgressWidth();
    }

    public void setRightProgressValue(int progress) {
        mRightValue += progress;
        resetProgressWidth();
    }

    public int getLeftProgressValue() {
        return mLeftValue;
    }

    public int getRightProgressValue() {
        return mRightValue;
    }

    private int calculateTotalProgressValue() {
        return mLeftValue + mRightValue;
    }

    /**
     * 计算左进度的宽度
     *
     * @return 左进度条的宽度
     */
    private int calculateLeftProgressWidth() {
        float ratio = mLeftValue / (float) mTotalValue;
        return (int) (getWidth() * ratio) - mLeftRightProgressSpacing * mProgressHeight;
    }

    /**
     * 计算右进度的宽度
     *
     * @return 右进度的宽度
     */
    private int calculateRightProgressWidth() {
        float ratio = mRightValue / (float) mTotalValue;
        return (int) (getWidth() * ratio - mLeftRightProgressSpacing * mProgressHeight);
    }

    /**
     * 重新设置左右进度条
     */
    private void resetProgressWidth() {
        mTotalValue = calculateTotalProgressValue();
        mLeftWidthX = calculateLeftProgressWidth();
        mRightWidthX = getWidth() - calculateRightProgressWidth();
        getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {
            @Override
            public void run() {
                invalidate();
            }
        });
    }

}
